package com.gzq.singleton.practice1;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 单例设计模式： 饿汉式：静态常量、静态代码块 懒汉式：方法锁、双重校验锁、静态内部类。 枚举。
 * 
 * @author Administrator
 *
 */
public class DCL implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static void main(String[] args)
			throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException, IOException, ClassNotFoundException, InterruptedException {
		DCL singleton1 = DCL.getSingleton();
		DCL singleton2 = DCL.getSingleton();
		DCL singleton3 = DCL.getSingleton();
		DCL singleton4 = DCL.getSingleton();
		System.out.println(singleton1);
		System.out.println(singleton2);

		Constructor<DCL> declaredConstructor = DCL.class.getDeclaredConstructor();
		DCL newInstance = declaredConstructor.newInstance();
		System.out.println(newInstance);

		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(singleton1);
		byte[] byteArray = baos.toByteArray();

		ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
		ObjectInputStream ois = new ObjectInputStream(bais);
		Object readObject = ois.readObject();
		System.out.println(readObject);
	}

	private static DCL singleton;
	private static boolean finished = false;

	private DCL() {
	}

	public static DCL getSingleton() throws InterruptedException {
		if (!finished) {
			synchronized (DCL.class) {
				if (!finished) {
					singleton = new DCL();
					// 复杂初始化流程
					Thread.sleep(3000);
					finished = true;
				}
			}
		}
		return singleton;
	}
}
